package com.qujia.station.service.impl;


import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.qujia.common.config.QuJiaConfig;
import com.qujia.common.core.domain.AjaxResult;
import com.qujia.common.core.domain.ResultData;
import com.qujia.common.core.domain.model.LoginUser;
import com.qujia.common.core.redis.RedisCache;
import com.qujia.common.exception.CustomException;
import com.qujia.common.utils.*;
import com.qujia.customer.domain.CustomerCardSetting;
import com.qujia.customer.service.ICustomerCardSettingService;
import com.qujia.customer.service.ICustomerElectronicCardService;
import com.qujia.enums.ActionTypeEnum;
import com.qujia.enums.RecordTypeEnum;
import com.qujia.enums.integralTypeEnum;
import com.qujia.integral.domain.CustomerPointsRecord;
import com.qujia.integral.mapper.CustomerPointsRecordMapper;
import com.qujia.integral.service.ICustomerPointsRecordService;
import com.qujia.label.domain.CustomerLabelDemo;
import com.qujia.label.service.ICustomerLabelDemoService;
import com.qujia.station.domain.*;
import com.qujia.station.domain.dto.MemberNumDto;
import com.qujia.station.domain.vo.CustomMessages;
import com.qujia.station.domain.vo.YunHuaUserVo;
import com.qujia.station.domain.vo.appUserNumberVo;
import com.qujia.station.enums.UserSourceEnum;
import com.qujia.station.mapper.AppUserInfoMapper;
import com.qujia.station.mapper.AppUserSuperDetailMapper;
import com.qujia.station.mapper.OilMapper;
import com.qujia.station.mapper.StationMapper;
import com.qujia.station.service.*;
import com.qujia.station.utils.*;
import com.qujia.system.domain.HttpRequestUtil;
import com.qujia.system.service.ISysStationUserService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

/**
 * 油站信息Service业务层处理
 *
 * @author qujia
 * @date 2020-12-08
 */
@Service
@Slf4j
public class AppUserInfoServiceImpl implements IAppUserInfoService
{


    @Autowired
    private AppUserInfoMapper appUserInfoMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private CustomerPointsRecordMapper customerPointsRecordMapper;

    @Autowired
    private StationMapper stationMapper;

    @Value("${domain.name}")
    private  String domainName;
    @Autowired
    private ICustomerElectronicCardService customerElectronicCardService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private ICustomerCardSettingService customerCardSettingService;

    @Value("${qujia.yunHuaSyncGetUserIdUrl}")
    private String yunHuaSyncGetUserIdUrl;

    @Autowired
    private IdempotentUtil idempotentUtil;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Value("${qujia.yunHuaSyncUserUrl}")
    private String yunHuaSyncUserUrl;
    @Autowired
    private IGradeService gradeService;

    @Autowired
    private OilMapper oilMapper;
    @Value("${qujia.payBaseUrl}")
    private String payBaseUrl;
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AppUserSuperDetailMapper appUserSuperDetailMapper;
    @Autowired
    private ICustomerPointsRecordService customerPointsRecordService;

    @Autowired
    private IPhysicalCardService physicalCardService;
    @Autowired
    private IUserVirtualGradeRelService userVirtualGradeRelService;
    @Autowired
    private ICustomerLabelDemoService customerLabelDemoService;

    @Autowired
    private ISysStationUserService stationUserService;


    @Override
    public void increaseShareCount(Long userId) {
        appUserInfoMapper.increaseShareCount(userId);
    }

    @Override
    public void increaseTruckNumber(@Param("truckNumber") String truckNumber, @Param("userId") Long userId) {
        appUserInfoMapper.increaseTruckNumber(truckNumber, userId);
    }

    @Override
    public Integer getShareCountByUserId(Long userId) {
        return appUserInfoMapper.getShareCountByUserId(userId);
    }

    /**
     * 查询会员信息
     *
     * @param userId 会员信息
     * @return 会员信息
     */
    public SysAppUserInfo selectAppUserInfoById(Long userId) {
        return appUserInfoMapper.selectAppUserInfoById(userId);
    }

    @Override
    public SysAppUserInfo selectAppUserInfoByPhone(String phone) {
        return appUserInfoMapper.selectAppUserInfoByPhone(phone);
    }

    @Override
    public List<SysAppUserInfo> getAppUserInfoByPhoneAndStationId(String mobilePhone, Long stationId) {
        Map<String, Object> params = new HashMap<>();
        params.put("mobilePhone", mobilePhone);
        params.put("stationId", stationId);
        return appUserInfoMapper.selectAppUserInfoByPhoneAndStationId(params);
    }

    /**
     * 导入会员数据
     *
     * @param userList        用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return 结果
     */
    @Override
    @Transactional
    public String importAppUserInfo(List<SysAppUserInfo> userList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(userList) || userList.size() == 0) {
            throw new CustomException("导入会员数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (SysAppUserInfo user : userList) {
            try {
                List<SysAppUserInfo> u = new ArrayList<>();
                if (user.getMobilePhone() != null && !user.getMobilePhone().isEmpty()) {
                    // 验证是否存在这个手机号
                    Map<String, Object> params = new HashMap<>();
                    params.put("mobilePhone", user.getMobilePhone());
                    params.put("stationId", user.getStationId());
                    u = appUserInfoMapper.selectAppUserInfoByPhoneAndStationId(params);
                    // 继续处理 u 对象
                }
                if (StringUtils.isNotEmpty(u)) {
                    LocalDateTime currentDateTime = LocalDateTime.now();
                    user.setUpdateDate(currentDateTime.toString());
                }
                if (StringUtils.isEmpty(u)) {
                    user.setCreateBy(operName);
                    LocalDateTime currentDateTime = LocalDateTime.now();
                    Instant instant = currentDateTime.atZone(ZoneId.systemDefault()).toInstant();
                    Date date = Date.from(instant);
                    user.setCreateTime(date);

                    user.setUpdateDate(currentDateTime.toString());
                    user.setUpdateTime(date);
                    user.setIntegral(MathUtil.add(null, user.getIntegral()));
                    user.setUserSource(UserSourceEnum.BACKEND.getValue());
                    user.setRegisteDate(date);
                    this.insertAppUserInfo(user);
                    //记录积分
                    importIntegral(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、会员 " + user.getName() + " 导入成功");
                } else if (isUpdateSupport) {
                    user.setUpdateBy(operName);
                    this.updateMember(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、会员 " + user.getName() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、会员 " + user.getName() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、会员 " + user.getName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());

            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            return failureMsg.toString();
//            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 积分导入明细记录
     *
     * @param user
     */
    private void importIntegral(SysAppUserInfo user) {
        //记录积分
        List<String> stationIds = stationUserService.selectStationIdByEnterpriseId(user.getStationId());
        if (null == stationIds || stationIds.size() < 1) {
            throw new CustomException("导入的油企下不存在油站！");
        }
        CustomerPointsRecord customerPointsRecord = new CustomerPointsRecord();
        customerPointsRecord.setRecordType(RecordTypeEnum.INCREASE.getName());
        customerPointsRecord.setIntegral(user.getIntegral());
        customerPointsRecord.setCreateTime(new Date());
        customerPointsRecord.setStationId(Long.valueOf(stationIds.get(0)));
        customerPointsRecord.setMobilePhone(user.getMobilePhone());
        customerPointsRecord.setAction(ActionTypeEnum.MANUAL_IMPORT.getName());
        Random random = new Random();
        String result1 = "";
        for (int i = 0; i < 6; i++) {
            result1 += random.nextInt(10);
        }
        String ordNo = System.nanoTime() + result1;
        customerPointsRecord.setOrderNo(ordNo);
        customerPointsRecordMapper.insertCustomerPointsRecord(customerPointsRecord);
    }

    /**
     * 查询会员统计信息
     *
     * @param appUserInfo 会员信息
     * @return 油罐信息
     */
    public SysAppUserInfo selectAppUserInfoSum(SysAppUserInfo appUserInfo) {
        return appUserInfoMapper.selectAppUserInfoSum(appUserInfo);
    }

    /**
     * 查询会员信息列表
     *
     * @param appUserInfo 会员信息
     * @return 会员信息集合
     */
    public List<SysAppUserInfo> selectAppUserInfoList(SysAppUserInfo appUserInfo) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        if (null != appUserInfo.getBeginTime() && null != appUserInfo.getEndTime()) {
            LocalDateTime startTime = LocalDateTime.parse(appUserInfo.getBeginTime(), formatter);
            LocalDateTime endTime = LocalDateTime.parse(appUserInfo.getEndTime(), formatter);
            if (startTime.isAfter(endTime)) {
                throw new CustomException("开始时间不能在结束时间之后");
            }

            String formattedStartTime = startTime.format(formatter);
            String formattedEndTime = endTime.format(formatter);
            appUserInfo.setBeginTime(formattedStartTime);
            appUserInfo.setEndTime(formattedEndTime);
        }


        log.info("查询会员信息列表：{}", appUserInfo);
        List<SysAppUserInfo> appUserInfoList = appUserInfoMapper.selectAppUserInfoList(appUserInfo);
        Map<Long, CustomerCardSetting> cardUseRangeMap = new HashMap<>();
        Map<Long, List<Grade>> gradeMap = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        for (SysAppUserInfo userInfo : appUserInfoList) {
            //常加油站id 转换成常加油品
            if (Objects.nonNull(userInfo) && Objects.nonNull(userInfo.getOilId())) {
                Oil oil = oilMapper.selectOilById(userInfo.getOilId());
                if (Objects.nonNull(oil) && StringUtils.isNotEmpty(oil.getOilName())
                        && StringUtils.isNotEmpty(oil.getOilClass())) {
                    userInfo.setUsualOilName(oil.getOilName() + oil.getOilClass());
                }
            }
            userInfo.setBalance(BigDecimal.ZERO);
            if (MobilePhoneUtil.isFakePhone(userInfo.getMobilePhone())) {
                continue;
            }
            Long enterpriseId = userInfo.getStationId();

            CustomerCardSetting setting = cardUseRangeMap.get(enterpriseId);
            if (setting == null) {
                CustomerCardSetting form = new CustomerCardSetting();
                form.setEnterpriseId(enterpriseId);
                List<CustomerCardSetting> settingList = customerCardSettingService.selectCustomerCardSettingList(form);
                if (settingList.isEmpty()) {
                    setting = new CustomerCardSetting();
                    cardUseRangeMap.put(enterpriseId, setting);
                } else {
                    setting = settingList.get(0);
                }
                if (StringUtils.isNotBlank(setting.getCardOilsType())) {
                    setting.setCardOilsTypeList(Arrays.asList(StringUtils.split(setting.getCardOilsType(), ",")));
                }
                cardUseRangeMap.put(enterpriseId, setting);
            }
            if (StringUtils.equals("1", setting.getCardEnabledFlag()) && !CollectionUtils.isEmpty(setting.getCardOilsTypeList())) {
                BigDecimal balance = customerElectronicCardService.getCustomerElectronicCardBalance(userInfo.getMobilePhone(),
                        enterpriseId.intValue(),
                        StringUtils.equals("1", setting.getCardUseRangeFlag()),
                        setting.getCardOilsTypeList());
                userInfo.setBalance(balance);
            }
            UserVirtualGradeRel userVirtualGradeRel = userVirtualGradeRelService.queryUserVirtualGrade(userInfo.getStationId(), userInfo.getUserId(), now);
            if (userVirtualGradeRel != null) {
                userInfo.setMemberLevel(userVirtualGradeRel.getGradeCode());
            } else {
                List<Grade> gradeList = gradeMap.get(enterpriseId);
                if (gradeList == null) {
                    Grade grade = new Grade();
                    grade.setEnterpriseId(enterpriseId);
                    grade.setDeleteFlag("0");
                    gradeList = gradeService.selectGradeList(grade);
                    gradeMap.put(enterpriseId, gradeList);
                }
                userInfo.setMemberLevel(getUserGradeCode(userInfo.getGrowUpValue(), gradeList));
            }

            // 查询实体卡总余额
            List<PhysicalCard> physicalCardList = physicalCardService.selectPhysicalCardByAppUserId(userInfo.getUserId().intValue());
            BigDecimal totalBalanceAmount = BigDecimal.ZERO;
            if (CollectionUtils.isNotEmpty(physicalCardList)) {
                for (PhysicalCard physicalCard : physicalCardList) {
                    if (Objects.nonNull(physicalCard)) {
                        totalBalanceAmount.add(Objects.nonNull(physicalCard.getPhysicalCardAmount()) ? physicalCard.getPhysicalCardAmount() : BigDecimal.ZERO);
                    }
                }
                userInfo.setTotalBalanceAmount(totalBalanceAmount);
            } else {
                userInfo.setTotalBalanceAmount(totalBalanceAmount);
            }
        }
//        String inputPattern="EEE MMM dd HH:mm:ss zzz yyyy";
//        String outputPattern="yyyy-MM-dd";
//        String timeZone = "Asia/Shanghai";
//        for(SysAppUserInfo appUser:appUserInfoList){
//            if (StringUtils.isNotBlank(appUser.getBirthday())){
//                appUser.setBirthday(formatDate(appUser.getBirthday(),inputPattern,outputPattern,timeZone));
//            }
//        }
        return appUserInfoList;
    }

    private String getUserGradeCode(Long growUpValue, List<Grade> grades) {
        if (grades.isEmpty()) {
            return "1";
        }
        String name = grades.get(0).getGradeCode();
        int size = grades.size();
        int li = size - 1;
        for (int i = 1; i < size; i++) {
            Grade grade = grades.get(i);
            if (grade.getGradeGrowValue() > growUpValue) {
                name = grades.get(i - 1).getGradeCode();
                break;
            }
            if (i == li) {
                name = grade.getGradeCode();
            }
        }
        return name;
    }

    /**
     * 查询会员信息列表
     *
     * @param customerLabelDemo 会员信息
     * @return 会员信息集合
     */
    public List<CustomerLabelDemo> selectAppUserInfoListForCoupon(CustomerLabelDemo customerLabelDemo) {
        List<CustomerLabelDemo> customerLabelDemoList = appUserInfoMapper.selectAppUserInfoListForCoupon(customerLabelDemo);

        return customerLabelDemoList;
    }

    /**
     * 将指定格式的日期字符串转换为另一种格式的日期字符串
     *
     * @param dateString    日期字符串
     * @param inputPattern  输入格式
     * @param outputPattern 输出格式
     * @param timeZone      时区
     * @return 转换后的日期字符串
     */
    public static String formatDate(String dateString, String inputPattern, String outputPattern, String timeZone) {
        SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern, Locale.ENGLISH);
        inputFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
        SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern);
        try {
            Date date = inputFormat.parse(dateString);
            String outputDateString = outputFormat.format(date);
            return outputDateString;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 添加会员积分
     *
     * @param appUserInfo 会员信息
     * @return 会员信息集合
     */
    @Transactional
    @Override
    public int addAppUserPoints(SysAppUserInfo appUserInfo) {
        SysAppUserInfo sysAppUserInfo = selectAppUserInfoById(appUserInfo.getUserId());
        String timeStr1 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        sysAppUserInfo.setUpdateDate(timeStr1);
        if (sysAppUserInfo != null && sysAppUserInfo.getIntegral() != null) {
            Long newpoints = 0L;
            if (appUserInfo.getType() == 1) {
                newpoints = sysAppUserInfo.getIntegral() + appUserInfo.getAddPoints();
            } else if (appUserInfo.getType() == 0) {
                if (sysAppUserInfo.getIntegral() - appUserInfo.getAddPoints() < 0) {
                    throw new CustomException("该用户积分不够扣减");
                }
                newpoints = sysAppUserInfo.getIntegral() - appUserInfo.getAddPoints();
            }
            sysAppUserInfo.setIntegral(newpoints);
        } else {
            sysAppUserInfo.setIntegral(appUserInfo.getAddPoints());
        }

        Station station = new Station();
        station.setEnterpriseId(sysAppUserInfo.getStationId());
        List<Station> stlist = stationMapper.selectStationList(station);
        CustomerPointsRecord customerPointsRecord = new CustomerPointsRecord();
        customerPointsRecord.setRecordType(appUserInfo.getType() == 1 ? "+" : "-");
        customerPointsRecord.setIntegral(Long.parseLong(appUserInfo.getAddPoints() + ""));
        customerPointsRecord.setCreateTime(new Date());
        customerPointsRecord.setStationId(stlist.get(0).getStationId());
        customerPointsRecord.setMobilePhone(sysAppUserInfo.getMobilePhone());
        customerPointsRecord.setAction(appUserInfo.getType() == 1 ? integralTypeEnum.MANUAL_ADDITION : integralTypeEnum.MANUAL_REDUCTION);
        customerPointsRecordMapper.insertCustomerPointsRecord(customerPointsRecord);
        customerPointsRecordService.wxgzhIntegralPush(customerPointsRecord);
        return appUserInfoMapper.updateAppUserInfo(sysAppUserInfo);
    }

    /**
     * 向云华发送信息
     *
     * @param appUserInfo 会员信息
     * @return 会员信息集合
     */
    @Override
    public int sendUserToYunHua(SysAppUserInfo appUserInfo) {
        try {

            YunHuaSendUser yunHuaSendUser = new YunHuaSendUser();
            yunHuaSendUser.setMobilePhone(appUserInfo.getMobilePhone());
            yunHuaSendUser.setPlatformId("106");
            yunHuaSendUser.setSystemId("10");
            Sha256SignCreator sha256SignCreator = new Sha256SignCreator();
            String sign = sha256SignCreator.encode(JSONObject.parseObject(yunHuaSendUser.toBeforeRequest()), "4wv8umq3wd");
            yunHuaSendUser.setSign(sign);
//            res=  HttpUtils.connectPostUrl("http://123.60.22.157:31120/marketing/pay/unionPay", yunHuaParam.toRequest());
            String mmmmm = yunHuaSendUser.toRequest();
            String res = HttpUtils.connectPostUrl("https://ai-oil-test01.xailife.com:30443/ai-oil-user/consumer/sync/add", mmmmm);
            JSONObject result = JSONObject.parseObject(res);
            String userId = result.getString("data");
            appUserInfo.setYunhuaUserId(userId);
            return appUserInfoMapper.updateAppUserInfo(appUserInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public int syncYunHuaUser(String mobilePhone, String enterpriseId) {
        try {
            YunHuaSyncUser yunHuaSendUser = new YunHuaSyncUser();
            yunHuaSendUser.setMobilePhone(mobilePhone);
            yunHuaSendUser.setPlatformId("106");
            yunHuaSendUser.setSystemId("10");
            Sha256SignCreator sha256SignCreator = new Sha256SignCreator();
            String sign = sha256SignCreator.encode(JSONObject.parseObject(yunHuaSendUser.toBeforeRequest()), "4wv8umq3wd");
            yunHuaSendUser.setSign(sign);
//            res=  HttpUtils.connectPostUrl("http://123.60.22.157:31120/marketing/pay/unionPay", yunHuaParam.toRequest());
            String mmmmm=yunHuaSendUser.toRequest();
            String res=  HttpUtils.connectPostUrl("https://ai-oil-dev02.xailife.com:30443/ai-oil-account/userInfo/sync", mmmmm);
            JSONObject result=JSONObject.parseObject(res);
            String  userId=result.getString("data");
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;

    }

    @Override
    public String getYunHuaUserId(String mobilePhone) {
        try {
            YunHuaSendUser yunHuaSendUser = new YunHuaSendUser();
            yunHuaSendUser.setMobilePhone(mobilePhone);
            yunHuaSendUser.setPlatformId("106");
            yunHuaSendUser.setSystemId("10");
            Sha256SignCreator sha256SignCreator = new Sha256SignCreator();
            String sign = sha256SignCreator.encode(JSONObject.parseObject(yunHuaSendUser.toBeforeRequest()), "4wv8umq3wd");
            yunHuaSendUser.setSign(sign);
//            res=  HttpUtils.connectPostUrl("http://123.60.22.157:31120/marketing/pay/unionPay", yunHuaParam.toRequest());
            String mmmmm = yunHuaSendUser.toRequest();
            String res = HttpUtils.connectPostUrl(yunHuaSyncGetUserIdUrl, mmmmm);
            JSONObject result = JSONObject.parseObject(res);
            String userId = result.getString("data");
            return userId;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private List<YunHuaUser> getYunHuaUserFromYunHua(List<YunHuaUserVo> yunHuaUserVoList) {
        YunHuaBatchSyncUser yunHuaBatchSyncUser = new YunHuaBatchSyncUser();
        yunHuaBatchSyncUser.setSsUserInfoDtos(yunHuaUserVoList);
        yunHuaBatchSyncUser.setPlatformId("106");
        yunHuaBatchSyncUser.setSystemId("10");
        yunHuaBatchSyncUser.setSignType("SHA256");
        Sha256SignCreator sha256SignCreator = new Sha256SignCreator();
        String sign = sha256SignCreator.encode(JSONObject.parseObject(JSON.toJSONString(yunHuaBatchSyncUser)), "4wv8umq3wd");
        yunHuaBatchSyncUser.setSign(sign);
//            String res=  HttpUtils.connectPostUrl("https://ai-oil-dev02.xailife.com:30443/ai-oil-account/userInfo/batchSync", mmmmm);
        String body = HttpRequest.post(yunHuaSyncUserUrl).body(JSON.toJSONString(yunHuaBatchSyncUser)).execute().body();
        log.info("批量同步结果{}", body);
        JSONObject result = JSONObject.parseObject(body);
        String data = result.getString("data");

        Gson gson = new Gson();
        List<YunHuaUser> yunHuaUserList = gson.fromJson(data, new TypeToken<List<YunHuaUser>>() {
        }.getType());

        return yunHuaUserList;
    }

    @Override
    @Async("threadPoolTaskExecutor")
    public void batchUserToYunHua(List<YunHuaUserVo> yunHuaUserVoList) {

        log.info("开始从云化获取userid");
        List<YunHuaUser> yunHuaUserList = getYunHuaUserFromYunHua(yunHuaUserVoList);

        if (CollectionUtils.isEmpty(yunHuaUserList)) {
            return;
        }

        //更新状态
        List<List<YunHuaUser>> lists = SplitListUtils.splitList(20, yunHuaUserList.size(), yunHuaUserList);
        CountDownLatch countDownLatch = new CountDownLatch(lists.size());

        for (List<YunHuaUser> itemList : lists) {
            try {
                appUserInfoMapper.updateIsSyncAndIdByPhone(itemList);
            } finally {
                countDownLatch.countDown();
            }
        }
    }

    @Override
    @Async("threadPoolTaskExecutor")
    public void updateUserMemberCode(Long enterpriseId) {


        Enterprise enterprise = enterpriseService.selectEnterpriseById(enterpriseId);
        //油企账号
        if (Objects.nonNull(enterprise)){

            List<SysAppUserInfo> sysAppUserInfoList = appUserInfoMapper.getappMemberCodeIsNull(enterpriseId);
            if (CollectionUtils.isEmpty(sysAppUserInfoList)) {
                return;
            }
            Date begn = new Date();
            log.info("更新会员编码开始时间：{}",begn);
            CountDownLatch countDownLatch = new CountDownLatch(sysAppUserInfoList.size());
            for (SysAppUserInfo sysAppUserInfo : sysAppUserInfoList) {
                try {
                    boolean b = true;
                    String memberCode = "";
                    while (b) {
                        memberCode = LocalDateUtils.format(LocalDateTime.now(), "yyMMddSS") + RandomStringUtils.randomNumeric(5);
                        int have  = appUserInfoMapper.RepeatOrNotMemberCode(memberCode);
                        if (have == 0) {
                            b = false;
                        }
                    }
                    sysAppUserInfo.setMemberCode(memberCode);
                    sysAppUserInfo.setUpdateDate(LocalDateUtils.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                    appUserInfoMapper.updateMemberCode(sysAppUserInfo);
                }catch (RuntimeException e){
                    log.error("更新会员编码异常：",e);
                }finally {
                    countDownLatch.countDown();
                }
            }
            Date date = new Date();
            log.info("更新会员编码结束时间：{}",date);
        } else {
            throw  new CustomException("更新会员编码：该油企不存在，请传入正确的油企id...");
        }
    }

    @Override
    public SysAppUserInfo getUserRegisteDateByPhoneAndStationId(String mobilePhone, Long stationId) {
        return appUserInfoMapper.getUserRegisteDateByPhoneAndStationId(mobilePhone, stationId);
    }

    @Override
    public appUserNumberVo getAppUserNumber(SysAppUserInfo appUserInfo) {

        log.info("获取会员数量入参:油企id：{} 开始时间：{} 结束时间：{}", appUserInfo.getStationId(), appUserInfo.getBeginTime(), appUserInfo.getEndTime());

        if (null != appUserInfo.getEndTime() && null != appUserInfo.getBeginTime()) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            LocalDateTime startTime = LocalDateTime.parse(appUserInfo.getBeginTime(), formatter);
            LocalDateTime endTime = LocalDateTime.parse(appUserInfo.getEndTime(), formatter);
            if (startTime.isAfter(endTime)) {
                throw new CustomException("开始时间不能在结束时间之后");
            }

            String formattedStartTime = startTime.format(formatter);
            String formattedEndTime = endTime.format(formatter);
            appUserInfo.setBeginTime(formattedStartTime);
            appUserInfo.setEndTime(formattedEndTime);

        }

        Long appNewUserNumber = appUserInfoMapper.getAppNewUserNumber(appUserInfo);
        Long appUserSum = appUserInfoMapper.getAppUserSum(appUserInfo);
        return appUserNumberVo.builder().appUserSum(appUserSum).newUserNumber(appNewUserNumber).build();
    }

    /**
     * 清除redis的内容
     *
     * @param enterprise 清除缓存
     * @return 发送会员信息
     */
    public AjaxResult clearRedis(Enterprise enterprise) {
        redisCache.deleteObject("access_token_" + enterprise.getGzhAppId());
        //判断当前的信息是正式的还是测试的网址
        int success = 0;
        int erro = 0;
        String tokeurl = "";
        String mm = QuJiaConfig.getUploadPath();
        if ("/mnt/uploadfile/images//upload".equals(QuJiaConfig.getUploadPath())) {

            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";
        } else {

            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";
        }
        // redisCache.deleteObject("access_token_"+enterprise.getGzhAppId());
        String token = "";
        token = redisCache.getCacheObject("access_token_" + enterprise.getGzhAppId());
        if ("".equals(token) || token == null) {

            String tokenJson = "{\n" +
                    "    \"appId\":\"" + enterprise.getGzhAppId() + "\",\n" +
                    "    \"appSecret\":\"" + enterprise.getGzhAppSecret() + "\"\n" +
                    "}";
            JSONObject tokenmessage = HttpRequestUtil.getHttpsRequestData(tokeurl, "POST", tokenJson);
            Integer mm1 = tokenmessage.getInteger("retCode");
            if (tokenmessage.getInteger("retCode") != 0) {
                return AjaxResult.error("请求获取token失败");
            }
            token = tokenmessage.getString("data");
        }
        if ("".equals(token) || token == null) {
            return AjaxResult.error("无法获取token信息");
        }
        return AjaxResult.success("成功");
    }

    /**
     * 查询新用户
     *
     * @param enterpriseId 油企id
     * @return 会员信息
     */
    public List<SysAppUserInfo> selectNewAppUser(Long enterpriseId) {
        return appUserInfoMapper.selectNewAppUser(enterpriseId);
    }

    /**
     * 发送信息
     *
     * @param sendMessage 发送信息
     * @return 发送会员信息
     */
    public AjaxResult sendMessageToUser(SendMessage sendMessage, Enterprise enterprise) {

        int success = 0;
        int erro = 0;

//        String tokeurl="";
//        if("/mnt/uploadfile/images//upload".equals(QuJiaConfig.getUploadPath())){
//
//            //tokeurl="https://test.91cheyibao.com/apipay/getAccessTokenFromSaas";
//            tokeurl="https://mp.huijy.net/prod/getAccessTokenFromSaas";
//
//        }else {
//
//            tokeurl="https://mp.huijy.net/prod/getAccessTokenFromSaas";
//        }
//        // redisCache.deleteObject("access_token_"+enterprise.getGzhAppId());
//        String token="";
//        token  = redisCache.getCacheObject("access_token_"+enterprise.getGzhAppId());
//        if("".equals(token)||token==null){
//
//            String tokenJson="{\n" +
//                    "    \"appId\":\""+enterprise.getGzhAppId()+"\",\n" +
//                    "    \"appSecret\":\""+enterprise.getGzhAppSecret()+"\"\n" +
//                    "}";
//            JSONObject tokenmessage=HttpRequestUtil.getHttpsRequestData(tokeurl,"POST",tokenJson);
//
//            if(tokenmessage.getInteger("retCode")!=0){
//                return  AjaxResult.error("请求获取token失败");
//            }
//            token=tokenmessage.getString("data");
//        }
//        if("".equals(token)||token==null){
//            return AjaxResult.error("无法获取token信息");
//        }

        //改为模板消息发送
        for (String openid : sendMessage.getOpenIdList()) {
            if (push(openid, enterprise, sendMessage.getMessage()) == 0) {
                erro++;
            } else {
                success++;
            }
        }
//        String url="https://api.weixin.qq.com/card/membercard/updateuser?access_token="+token;
//        String method="POST";
//        //微信创建卡卷所需要的参数，string转换之后，可能会报参数类型错误，尽量是直接从json串中复制过来
//     for(String code:sendMessage.getCodeList()) {
//         String mes = "{\n" +
//                 "    \"code\": \"" + code + "\",\n" +
//                 "     \"card_id\": \"" + enterprise.getCardId() + "\",\n" +
//                 "    \"record_bonus\": \"" + sendMessage.getMessage() + "\",\n" +
//                 "     \"add_bonus\": 1,\n" +
//                 "    \"record_balance\": \"赠送1个积分值\",\n" +
//                 "    \"notify_optional\": {\n" +
//                 "        \"is_notify_bonus\": true,\n" +
//                 "        \"is_notify_balance\": false,\n" +
//                 "        \"is_notify_custom_field1\":false\n" +
//                 "    }\n" +
//                 "}";
//         JSONObject message = HttpRequestUtil.getHttpsRequestData(url, method, mes);
//         if (!"0".equals(message.getString("errcode"))) {
//             erro++;
//         } else {
//             success++;
//         }
//     }
        if (success == 0) {
            return AjaxResult.error("信息发送失败");
        }
        return AjaxResult.success("成功发送" + success + "人，" + "失败" + erro + "人");
    }


    /*
     * 微信公众号推送
     * @param appId
     * @param appSecret
     * @param templateId
     * @param openId
     * @param wxMpTemplateDataList
     */
    public Integer push(String openId, Enterprise enterprise, String sendMessage) {

        //创建对象
        WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //公众号token缓存处理
        //String tokenCache = weiXinUserUtil.getTokenByRedisCache(appId, appSecret);
        String tokenCache = "";

        String tokeurl = "";

        wxMpInMemoryConfigStorage.setAppId(enterprise.getGzhAppId());
        wxMpInMemoryConfigStorage.setSecret(enterprise.getGzhAppSecret());

        if ("/mnt/uploadfile/images//upload".equals(QuJiaConfig.getUploadPath())) {

            //tokeurl="https://test.91cheyibao.com/apipay/getAccessTokenFromSaas";
//            tokeurl="https://mp.huijy.net/prod/getAccessTokenFromSaas";
            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";

        } else {

//            tokeurl="https://mp.huijy.net/prod/getAccessTokenFromSaas";
            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";
        }
        // redisCache.deleteObject("access_token_"+enterprise.getGzhAppId());

        tokenCache = redisCache.getCacheObject("access_token_" + enterprise.getGzhAppId());
        if ("".equals(tokenCache) || tokenCache == null) {

            String tokenJson = "{\n" +
                    "    \"appId\":\"" + enterprise.getGzhAppId() + "\",\n" +
                    "    \"appSecret\":\"" + enterprise.getGzhAppSecret() + "\"\n" +
                    "}";
            JSONObject tokenmessage = HttpRequestUtil.getHttpsRequestData(tokeurl, "POST", tokenJson);
            Integer mm1 = tokenmessage.getInteger("retCode");

            tokenCache = tokenmessage.getString("data");
        }
        String url1 = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + tokenCache;
        String method = "POST";
        String mes = "    {\n" +
                "           \"touser\":\"" + openId + "\",\n" +
                "           \"template_id\":\"" + enterprise.getSendMessageTemplateId() + "\",\n" +
                "           \"data\":{\n" +
                "                   \"first\": {\n" +
                "                       \"value\":\"\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"keyword1\":{\n" +
                "                       \"value\":\"" + "" + "\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"keyword2\":{\n" +
                "                       \"value\":\"" + sdf.format(date) + "\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"remark\":{\n" +
                "                       \"value\":\"" + sendMessage.replace("\n", "\\n") + "\",\n" +
                "                       \"color\":\"#fc5531\"\n" +
                "                   }\n" +
                "           }\n" +
                "       }";


        JSONObject message = HttpRequestUtil.getHttpsRequestData(url1, method, mes);
        if (!"0".equals(message.getString("errcode"))) {
            return 0;
        } else {
            return 1;
        }


    }


    /*
     * 微信公众号推送
     * @param appId
     * @param appSecret
     * @param templateId
     * @param openId
     * @param wxMpTemplateDataList
     */
    public Integer push(String openId, Enterprise sysEnterpriseUser, String templateId, String sendMessage) {

        //创建对象
        WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();


        //公众号token缓存处理
        //String tokenCache = weiXinUserUtil.getTokenByRedisCache(appId, appSecret);
        String tokenCache = "";

        String tokeurl = "";

        wxMpInMemoryConfigStorage.setAppId(sysEnterpriseUser.getGzhAppId());
        wxMpInMemoryConfigStorage.setSecret(sysEnterpriseUser.getGzhAppSecret());

        if ("/mnt/uploadfile/images//upload".equals(QuJiaConfig.getUploadPath())) {


            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";

        } else {

            tokeurl = domainName + "/apipay/getAccessTokenFromSaas";
        }


        tokenCache = redisCache.getCacheObject("access_token_" + sysEnterpriseUser.getGzhAppId());
        if ("".equals(tokenCache) || tokenCache == null) {

            String tokenJson = "{\n" +
                    "    \"appId\":\"" + sysEnterpriseUser.getGzhAppId() + "\",\n" +
                    "    \"appSecret\":\"" + sysEnterpriseUser.getGzhAppSecret() + "\"\n" +
                    "}";
            JSONObject tokenmessage = HttpRequestUtil.getHttpsRequestData(tokeurl, "POST", tokenJson);
            Integer mm1 = tokenmessage.getInteger("retCode");

            tokenCache = tokenmessage.getString("data");
        }
        String url1 = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + tokenCache;
        String method = "POST";
        String mes = "    {\n" +
                "           \"touser\":\"" + openId + "\",\n" +
                "           \"template_id\":\"" + templateId + "\",\n" +
                "           \"data\":{\n" +
                "                   \"first\": {\n" +
                "                       \"value\":\"车辆保养提醒!\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"XM\":{\n" +
                "                       \"value\":\"" + "会员您好" + "\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"KH\":{\n" +
                "                       \"value\":\"" + "000001" + "\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"CONTENTS\":{\n" +
                "                       \"value\":\"" + "车辆需要定时保养" + "\",\n" +
                "                       \"color\":\"#ffffff\"\n" +
                "                   },\n" +
                "                   \"remark\":{\n" +
                "                       \"value\":\"" + sendMessage + "\",\n" +
                "                       \"color\":\"#20B2AA\"\n" +
                "                   }\n" +
                "           }\n" +
                "       }";


        JSONObject message = HttpRequestUtil.getHttpsRequestData(url1, method, mes);
        if (!"0".equals(message.getString("errcode"))) {
            return 0;
        } else {
            return 1;
        }


    }


    /**
     * 新增会员信息
     *
     * @param appUserInfo 会员信息
     * @return 结果
     */
    public int insertAppUserInfo(SysAppUserInfo appUserInfo) {
        return appUserInfoMapper.insertAppUserInfo(appUserInfo);
    }


    /**
     * 修改会员信息
     *
     * @param appUserInfo 会员信息
     * @return 结果
     */
    public int updateMember(SysAppUserInfo appUserInfo) {
        return appUserInfoMapper.updateMember(appUserInfo);
    }


    /**
     * 删除会员信息
     *
     * @param userId 会员信息ID
     * @return 结果
     */
    public int deleteAppUserInfoById(Long userId) {
        return appUserInfoMapper.deleteAppUserInfoById(userId);
    }


    /**
     * 批量删除会员信息
     *
     * @param userIds 需要删除的数据ID
     * @return 结果
     */
    public int deleteAppUserInfoByIds(Long[] userIds) {
        return appUserInfoMapper.deleteAppUserInfoByIds(userIds);
    }

    @Override
    public void restAppUserPassword(Long userId) {
        SysAppUserInfo updateUser = new SysAppUserInfo();
        updateUser.setUserId(userId);
        // 设置默认密码123456
        updateUser.setPayPassword(DESUtils.encrypt("123456"));
        appUserInfoMapper.updateAppUserInfo(updateUser);
    }

    @Override
    public SysAppUserInfo getOne(SysAppUserInfo appUserInfo) {
        return appUserInfoMapper.getOne(appUserInfo);
    }

    @Override
    public MemberNumDto selectMemberNum(PayOrder payOrder) {
        SysAppUserInfo appUserInfo = new SysAppUserInfo();
        AppUserSuperDetail appUserSuperDetail = new AppUserSuperDetail();
        if (Objects.nonNull(payOrder) && StringUtils.isNotEmpty(payOrder.getBeginTime())) {
            appUserInfo.setBeginTime(payOrder.getBeginTime());
            appUserSuperDetail.setBeginTime(payOrder.getBeginTime());
        }
        appUserSuperDetail.setEnterpriseIdListForAuthor(payOrder.getEnterpriseIdListForAuthor());
        appUserInfo.setEnterpriseIdListForAuthor(payOrder.getEnterpriseIdListForAuthor());
        if (Objects.nonNull(payOrder) && StringUtils.isNotEmpty(payOrder.getEndTime())) {
            appUserInfo.setEndTime(payOrder.getEndTime());
            appUserSuperDetail.setEndTime(payOrder.getEndTime());
        }

        // 获取权限下所有油企id
        List<Long> stationIdLists = new ArrayList<>();
        if (Objects.nonNull(payOrder)) {
            if (Objects.nonNull(payOrder.getEnterpriseId())) {
                stationIdLists.add(payOrder.getEnterpriseId());
            }
            if (CollectionUtils.isNotEmpty(payOrder.getStationIdList())) {
                payOrder.getStationIdList().stream().forEach(stationId -> {
                    Station station = stationMapper.selectStationById(Long.valueOf(stationId));
                    if (Objects.nonNull(station) && !stationIdLists.contains(station.getEnterpriseId())) {
                        stationIdLists.add(station.getEnterpriseId());
                    }
                });
            }

            if (Objects.nonNull(payOrder.getStationId())) {
                Station station = stationMapper.selectStationById(payOrder.getStationId());
                if (Objects.nonNull(station) && !stationIdLists.contains(station.getEnterpriseId())) {
                    stationIdLists.add(station.getEnterpriseId());
                }
            }
        }

        appUserInfo.setStationIdLists(stationIdLists);
        appUserSuperDetail.setEnterpriseIdList(appUserInfo.getStationIdLists());
        // 统计会员数量
        Long allMemberNum = 0l;
        allMemberNum = appUserInfoMapper.selectMemberNum(appUserInfo);

        // 统计超级会员数量
//        SysAppUserInfo todayAppUserInfo = appUserInfo;
//        todayAppUserInfo.setUserLevel("1");  不能这样取超级会员数量
//        Long superMemberNum = 0l;
//        superMemberNum = appUserInfoMapper.selectMemberNum(todayAppUserInfo);

        // 统计 今日新增会员数量
        String todayTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getTodayStartTime());
        appUserInfo.setBeginTime(todayTime);
        appUserInfo.setEndTime(null);
        Long todayMemberNum = 0l;
        todayMemberNum = appUserInfoMapper.selectMemberNum(appUserInfo);

        // 统计超级会员数量
        Long superMemberNum = appUserSuperDetailMapper.selectAppUserSuperDetail(appUserSuperDetail);

        MemberNumDto memberNum = new MemberNumDto();
        memberNum.setAllMemberNum(allMemberNum);
        memberNum.setTodayMemberNum(todayMemberNum);
        memberNum.setSuperMemberNum(superMemberNum);

        return memberNum;
    }

    @Override
    public ResultData sendMessageToUserNew(SendMessage sendMessage) {
        LoginUser current = SecurityUtils.getLoginUser();
        CustomMessages customMessages = new CustomMessages();
        customMessages.setEnterpriseId(current.getUser().getEnterpriseId());
        customMessages.setEnterpriseName(sendMessage.getEnterpriseName());
        customMessages.setMessage(sendMessage.getMessage());
        customMessages.setTitle(sendMessage.getTitle());
        customMessages.setOpenIdList(sendMessage.getOpenIdList());
        //改为模板消息发送
        ResultData resssultData = restTemplate.postForObject(payBaseUrl + "/sendMessageToUser", customMessages, ResultData.class);
        log.info("resssultData:{}", JSON.toJSONString(resssultData));
        return resssultData;
    }

    @Override
    public ResultData sendMessageToUserBatch(CustomerLabelDemo customerLabelDemo) {
        log.info("sendMessageToUserBatch:{}", customerLabelDemo);
        LoginUser current = SecurityUtils.getLoginUser();
        List<CustomerLabelDemo> list = new ArrayList<>();
        customerLabelDemo.setEnterpriseId(current.getUser().getEnterpriseId());
        if (customerLabelDemo.getEndCountNum() != null && customerLabelDemo.getEndCountNum() == 0) {
            list = customerLabelDemoService.selectNewAppUser(customerLabelDemo);
        } else {
            //开启二次查询
            list = customerLabelDemoService.secondCustomerLabelDemoList(customerLabelDemo);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            Enterprise enterprise = enterpriseService.selectEnterpriseById(current.getUser().getEnterpriseId());
            List<String> openIdList = list.stream().map(CustomerLabelDemo::getBlogOpenid).filter(s -> s != null).collect(Collectors.toList());
            log.info("openIdList:{}", JSON.toJSONString(openIdList));
            if (CollectionUtils.isNotEmpty(openIdList)) {
                int end = 0;
                int size = 500;
                for (int i = 0; i < openIdList.size(); ) {
                    if ((end + size) >= openIdList.size()) {
                        end = openIdList.size();
                    } else {
                        end += size;
                    }
                    List<String> stringList = openIdList.subList(i, end);
                    i += size;
                    SendMessage sendMessage = new SendMessage();
                    sendMessage.setOpenIdList(stringList);
                    sendMessage.setMessage(customerLabelDemo.getMessage());
                    sendMessage.setTitle(customerLabelDemo.getTitle());
                    sendMessage.setEnterpriseName(enterprise.getEnterpriseName());
                    log.info("sendMessageToUserBatch{}", sendMessage);
                    try {
                        sendMessageToUserNew(sendMessage);
                    } catch (Exception e) {
                        log.error("sendMessageToUserBatcherror:{}", e);
                    }
                }
            }
        }
        return ResultData.success();
    }

    @Override
    public boolean updateOpenId(Long userId) {
        return appUserInfoMapper.updateOpenId(userId) > 0;
    }

}
